package ai.engine;

import ai.AIConstant;
import ai.Trackable;
import ai.engine.factories.TaskFactory;
import util.ArrayList;
import util.List;

public abstract class Task {

	public short id;

	public short taskType;

	public Class taskDoerType; // AIUnit.class or AICity.class

	public String name;

	public String details;

	public byte status;

	public short priority;

	public Trackable target;

	public List assignedResources;

	public byte resourcesMin;

	public byte resourcesMax;

	public byte technoNeeded;

	public Task(short id, short taskType, Class taskDoerType, String name,
			String details, short priority, Trackable target,
			byte resourcesMin, byte resourcesMax) {
		this.id = id;
		this.taskType = taskType;
		this.taskDoerType = taskDoerType;
		this.name = name;
		this.details = details;
		this.status = AIConstant.STATUS_WAIT_4_RESOURCES;
		this.priority = priority;
		this.target = target;
		this.assignedResources = new ArrayList();
		this.resourcesMin = resourcesMin;
		this.resourcesMax = resourcesMax;
	}

	public List getAssignedResources() {
		return this.assignedResources;
	}

	public void assign(TaskDoer taskDoer) {
		if (taskDoer != null)
			this.assignedResources.add(taskDoer);
	}

	public abstract boolean isTaskSuitable(TaskDoer taskDoer)
			throws ClassCastException;

	public abstract short getFormula(TaskDoer taskDoer);

	public abstract byte getAction(TaskDoer taskDoer);

	public abstract List getAdditionalResourcesNeeded(); // List of Resource

	// Objects

	public abstract boolean isObjectiveAchieved();

	public void checkStatus() {
		if (assignedResources.size() < resourcesMin)
			setStatus(AIConstant.STATUS_WAIT_4_RESOURCES);
		if (isObjectiveAchieved())
			setStatus(AIConstant.STATUS_DONE);
	}

	public void setStatus(byte status) {
		this.status = status;
	}

	public String toString() {
		StringBuffer res = new StringBuffer("--> Task ").append(this.id)
				.append(": ").append(this.name);
		res.append("\n\tStatus\t").append(
				TaskFactory.getStatusName(this.status));
		res.append("\n\tPriority\t").append(this.priority).append(
				"\n\tResources min-max\t").append(this.resourcesMin)
				.append("-").append(this.resourcesMax);
		if (target != null)
			res.append("\n\tTarget\t").append(this.target.toString());
		else
			res.append("\n\tTarget\tNone");
		res.append("\n\tAssignedResources\t");

		if (this.assignedResources != null) {
			for (short i = 0; i < this.assignedResources.size(); i++) {
				if (assignedResources.get(i) instanceof AIUnit)
					res = res.append("\n\t\t").append(
							(AIUnit) this.assignedResources.get(i));
				if (assignedResources.get(i) instanceof AICity)
					res = res.append("\n\t\t").append(
							(AICity) this.assignedResources.get(i));
			}
		}

		res.append("\n");
		return res.toString();
	}

	public boolean equals(Task obj) {
		// TODO Auto-generated method stub
		return (obj.taskType == this.taskType && obj.target == this.target);
	}

}
